package com.inoneone.youba.mcht.util;


import org.springframework.util.Base64Utils;
import sun.security.jca.GetInstance;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description: DES/ECB/PKCS5Padding</br>
 * Date: 2017-07-24 20:15:09</br>
 *
 * @param
 * @author 姬远玄
 * @return
 * @since JDK 1.7
 */
public class DesUtil {
    private final static String KEY_DES = "DES";

    private final static String DES = "DES/ECB/PKCS5Padding";

    private final static String CHARSET = "UTF-8";

    static ThreadLocal<HashMap<String, Cipher>> ecipherHolder = new ThreadLocal<>();
    static ThreadLocal<HashMap<String, Cipher>> dcipherHolder = new ThreadLocal<>();

    private static Cipher getEcipherInstance(String key) {
        return getInstance(key, Cipher.ENCRYPT_MODE, ecipherHolder);
    }

    private static Cipher getDcipherInstance(String key) {
        return getInstance(key, Cipher.DECRYPT_MODE, dcipherHolder);
    }

    private static Cipher getInstance(String key, int mode, ThreadLocal<HashMap<String, Cipher>> holder)
    {
        HashMap<String, Cipher> cipherMap = holder.get();
        if(cipherMap == null)
        {
            cipherMap = new HashMap<>();
            holder.set(cipherMap);
        }

        Cipher cipher = cipherMap.get(key);
        if(cipher == null)
        {
            cipher = createEncrypter(key, mode);
            cipherMap.put(key, cipher);
        }

        return cipher;
    }

    /**
     * Creates a new instance of DesEncrypter.
     *
     * @param key
     * @throws Exception
     */
    private static Cipher createEncrypter(String key, int mode) {
        try {
            // 从原始密钥数据创建DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(key.getBytes(CHARSET));

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);

            SecretKey secureKey = keyFactory.generateSecret(dks);

            Cipher cipher = Cipher.getInstance(DES);
            // 用密钥初始化Cipher对象
            cipher.init(mode, secureKey);

            return cipher;

        } catch (Exception e) {
            throw new RuntimeException("初始化des出错", e);
        }
    }

    /**
     * encrypt:(des加密). <br/>
     *
     * @param str
     * @return
     * @throws Exception
     * @author 姬远玄
     * @since JDK 1.7
     */
    public static String encrypt(String str, String key) {
        try {
            return Base64Utils.encodeToString((getEcipherInstance(key).doFinal(str.getBytes(CHARSET))));
        } catch (Exception e) {
            throw new RuntimeException("des加密错误", e);
        }
    }

    /**
     * decrypt:(des解密). <br/>
     *
     * @param str
     * @return
     * @throws Exception
     * @author 姬远玄
     * @since JDK 1.7
     */
    public static String decrypt(String str, String key) {
        try {
            return new String(getDcipherInstance(key).doFinal(Base64Utils.decodeFromString(str)), CHARSET);
        } catch (Exception e) {
            throw new RuntimeException("des解密错误", e);
        }

    }
}
